home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / raytrace / radiance / simplerd.lha / simplerad / FinalFTP / Conv / Qmodel / qm2patch.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-26  |  15.2 KB  |  501 lines

  1. /**********************************************************************/
  2. /* qm2patch.c                                                         */
  3. /*                                                                    */
  4. /*  Purpose:    Convert QuickModel scene into Radiosity scene         */
  5. /*                                                                    */
  6. /*  Origin Programmers: John Buchanan                                 */
  7. /*                Pierre Poulin                                 */
  8. /*                                                                    */
  9. /*  Date:    29 November 1989                                      */
  10. /*  Detail:    This is a quick hack. It works if you don't group the */
  11. /*        objects and if you don't use any splines, surface of  */
  12. /*        revolution or extrusion.                              */
  13. /*                                                                    */
  14. /*  Programmer: Bernard Kwok                                          */
  15. /*  Date:       May 1992                                              */
  16. /*  Detail:     Modified to include surface patches. Changed from     */
  17. /*              Optik output to output patches for radiosity program  */
  18. /*              Point light sources are not allowed.                  */
  19. /*                                                                    */
  20. /* Copyright (C) 1992, Bernard Kwok                                   */
  21. /* All rights reserved.                                               */
  22. /* Revision 1.0                                                       */
  23. /* May, 1992                                                          */
  24. /**********************************************************************/
  25. #include <stdio.h>
  26. #include <math.h>
  27. #include "qm2patch.h"
  28. extern char *malloc();
  29.  
  30. float    value;                /* value read by the parser */
  31. vector    VectorRead = { 0., 0., 0., 1. };
  32. matrix    MatrixRead = {
  33.   1., 0., 0., 0.,
  34.   0., 1., 0., 0.,
  35.   0., 0., 1., 0.,
  36.   0., 0., 0., 1.
  37.   };
  38. matrix    scaleMatrix;
  39. matrix    rotateMatrix;
  40. matrix    translateMatrix;
  41. matrix    transfMatrix;
  42. matrix    primitiveMatrix;
  43.  
  44. int isScaleMatrix = FALSE;
  45. int isRotateMatrix = FALSE;
  46. int isTranslateMatrix = FALSE;
  47. int isTransfMatrix = FALSE;
  48.  
  49. int    defaultSurfaceUsed = FALSE;
  50. Colour    colour;
  51. float    diffuse;
  52. float    specular;
  53.  
  54. int totalid = 0;
  55. int premesh = 0;
  56.  
  57. #define TOO_SMALL 1e-10
  58. float SurfaceParm[2];   /* Surface parameters                         */
  59. surface SurfaceRead;    /* Surface points                             */
  60.  
  61. /**********************************************************************/
  62. /* Initialize the transformation matrix for an object. */
  63. /**********************************************************************/
  64. void Init_Matrix ()
  65. {
  66.   MxCopy (MatrixRead, transfMatrix);
  67.   isTransfMatrix = TRUE;
  68. }
  69.  
  70. /**********************************************************************/
  71. /* Calculate normal from 3 patch points */
  72. /**********************************************************************/
  73. void CalcNormal(p1, p2, p3, n)
  74.      double p1[3];
  75.      double p2[3], p3[3], n[3];
  76. {
  77.   vector u, v;
  78.   double length;
  79.   int i;
  80.  
  81.   for (i=0;i<3;i++) {
  82.     u[i] = p2[i] - p1[i];
  83.     v[i] = p3[i] - p1[i];
  84.   }
  85.   n[0] = u[1]*v[2] - u[2]*v[1]; 
  86.   n[1] = u[2]*v[0] - u[0]*v[2]; 
  87.   n[2] = u[0]*v[1] - u[1]*v[0]; 
  88.  
  89.   length = n[0]*n[0] + n[1]*n[1] + n[2]*n[2];
  90.   length = sqrt(length);
  91.   if (length <= 0.0) {
  92.     fprintf(stderr,"length %g too small, not normalizing\n", length);
  93.     fprintf(stderr,"u = %g,%g,%g; v=%g,%g,%g; n=%g,%g,%g\n", u[0],u[1],u[2],
  94.        v[0],v[1],v[2], n[0],n[1],n[2]);
  95.     exit(1);
  96.   } 
  97.   n[0] = n[0] / length;
  98.   n[1] = n[1] / length;
  99.   n[2] = n[2] / length;
  100.  
  101.   if (_ABS(n[0]) < TOO_SMALL) n[0] = 0.0;
  102.   if (_ABS(n[1]) < TOO_SMALL) n[1] = 0.0;
  103.   if (_ABS(n[2]) < TOO_SMALL) n[2] = 0.0;
  104.  
  105.   if (n[0] > 1.0 || n[1] > 1.0 || n[2] > 1.0) {
  106.     fprintf(stderr,"u = %g,%g,%g; v=%g,%g,%g; n=%g,%g,%g; l=%g\n", 
  107.         u[0],u[1],u[2], v[0],v[1],v[2], n[0],n[1],n[2], length);
  108.   }
  109. }
  110.  
  111. /**********************************************************************/
  112. /* Compare two vectors to see if equal                                */
  113. /**********************************************************************/
  114. int VComp(v1, v2)
  115.      float v1[5], v2[5];
  116. {
  117.   register int i;
  118.  
  119.   for(i=0;i<3;i++)
  120.     if (v1[i] != v2[i]) return 0;
  121.   return 1;
  122. }
  123.  
  124. /**********************************************************************/
  125. /* Output patch mesh for object                                       */
  126. /**********************************************************************/
  127. void OutputMeshed(namePrimitive, noObject)
  128.     char *namePrimitive;        /* name of the primitive */
  129.     int noObject;            /* number of the object */
  130. {
  131.   int i,j,k;
  132.   int patchid = 0;
  133.   int numpatchs = -1;
  134.   int num_vert = -1;
  135.   double patch_vert[4][3];
  136.   double patch_normal[3];
  137.   double tmp[3], tmp1[3], tmp2[3];
  138.  
  139.   if (premesh == 0) {
  140.     printf("    NumMeshes -1\n");
  141.  
  142.   } else if (premesh == 1) { 
  143.     printf("    NumMeshes 1\n");
  144.     numpatchs = (int) ((SurfaceParm[0]-1) * (SurfaceParm[1]-1));
  145.     printf("    Mesh mesh%s%d %d {\n", namePrimitive, noObject, numpatchs);
  146.     for (i=0;i<((int)SurfaceParm[0]-1);i++) {
  147.       for (j=0;j<((int)SurfaceParm[1]-1);j++) {
  148.  
  149.     patchid++;
  150.     num_vert = 4;
  151.     
  152.     /* Check for duplicate vertices, illegal patches (<= 2 sides) */
  153.     k = 0;
  154.     if (VComp(SurfaceRead[i][j], SurfaceRead[i+1][j]) || 
  155.         VComp(SurfaceRead[i][j], SurfaceRead[i][j+1]) ||
  156.         VComp(SurfaceRead[i][j], SurfaceRead[i+1][j+1])) {
  157.       num_vert--; 
  158.     } else {
  159.       patch_vert[k][0] = SurfaceRead[i][j][0];
  160.       patch_vert[k][1] = SurfaceRead[i][j][1];
  161.       patch_vert[k][2] = SurfaceRead[i][j][2];
  162.       k++;
  163.     }
  164.  
  165.     if (VComp(SurfaceRead[i][j+1], SurfaceRead[i+1][j]) ||
  166.         VComp(SurfaceRead[i][j+1], SurfaceRead[i+1][j+1])) {
  167.       num_vert--; 
  168.     } else {
  169.       patch_vert[k][0] = SurfaceRead[i][j+1][0];
  170.       patch_vert[k][1] = SurfaceRead[i][j+1][1];
  171.       patch_vert[k][2] = SurfaceRead[i][j+1][2]; 
  172.       k++;
  173.     }
  174.     
  175.     if (VComp(SurfaceRead[i+1][j], SurfaceRead[i+1][j+1])) {
  176.       num_vert--; 
  177.     } else {
  178.       patch_vert[k][0] = SurfaceRead[i+1][j+1][0];
  179.       patch_vert[k][1] = SurfaceRead[i+1][j+1][1];
  180.       patch_vert[k][2] = SurfaceRead[i+1][j+1][2];
  181.       k++;
  182.     }
  183.  
  184.     patch_vert[k][0] = SurfaceRead[i+1][j][0];
  185.     patch_vert[k][1] = SurfaceRead[i+1][j][1];
  186.     patch_vert[k][2] = SurfaceRead[i+1][j][2];
  187.  
  188.     if (num_vert > 2) {
  189.       /* Calculate and output patch normals */
  190.       tmp[0] = patch_vert[0][0]; tmp[1] = patch_vert[0][1];
  191.       tmp[2] = patch_vert[0][2];
  192.       CalcNormal(patch_vert[0], patch_vert[1], patch_vert[2], 
  193.              patch_normal);
  194.       patch_vert[0][0] = tmp[0]; patch_vert[0][1] = tmp[1];
  195.       patch_vert[0][2] = tmp[2];
  196.  
  197.       printf("    Patch norm%d %d {", patchid, num_vert);
  198.       for (k=0;k<num_vert;k++)
  199.         printf(" { %g %g %g }", patch_normal[0], patch_normal[1], 
  200.            patch_normal[2]);
  201.       printf(" }\n");      
  202.  
  203.  
  204.       /* Output patch vertices */
  205.       printf("    Patch vert%d %d {", patchid, num_vert);
  206.       for (k=0;k<num_vert;k++) {
  207.         if (_ABS(patch_vert[k][0]) < TOO_SMALL) patch_vert[k][0] = 0.0;
  208.         if (_ABS(patch_vert[k][1]) < TOO_SMALL) patch_vert[k][1] = 0.0;
  209.         if (_ABS(patch_vert[k][2]) < TOO_SMALL) patch_vert[k][2] = 0.0;
  210.         printf(" { %g %g %g }", patch_vert[k][0], patch_vert[k][1], 
  211.            patch_vert[k][2]);
  212.       }
  213.       printf(" }\n");
  214.     }
  215.       }
  216.     }
  217.     printf("    }\n");
  218.   }
  219. }
  220.  
  221. /**********************************************************************/
  222. /* Compute the transformation matrix and output the object in         */
  223. /* radiosity format                                                   */
  224. /**********************************************************************/
  225. void OutputObject (namePrimitive, noObject)
  226.     char *namePrimitive;        /* name of the primitive */
  227.     int noObject;            /* number of the object */
  228. {
  229.   matrix resultingMatrix;
  230.   
  231.   MxIdentity (resultingMatrix);
  232.   MxMultiply (resultingMatrix, primitiveMatrix, resultingMatrix);
  233.   
  234.   if (isScaleMatrix) {
  235.     MxMultiply (resultingMatrix, scaleMatrix, resultingMatrix);
  236.     isScaleMatrix = FALSE;
  237.   }
  238.   if (isRotateMatrix) {
  239.     MxMultiply (resultingMatrix, rotateMatrix, resultingMatrix);
  240.     isRotateMatrix = FALSE;
  241.   }
  242.   if (isTranslateMatrix) {
  243.     MxMultiply (resultingMatrix, translateMatrix, resultingMatrix);
  244.     isTranslateMatrix = FALSE;
  245.   }
  246.   if (isTransfMatrix) {
  247.     MxMultiply (resultingMatrix, transfMatrix, resultingMatrix);
  248.     isTransfMatrix = FALSE;
  249.   }
  250.  
  251.   /* Output header definition */
  252.   printf("\nObject %s%d %s {\n", namePrimitive, noObject, namePrimitive);
  253.  
  254.   /* Output matrix column order */
  255.   printf("    OWMatrix mat%s%d { %g %g %g %g %g %g %g %g %g %g %g %g }\n",
  256.      namePrimitive, noObject,
  257.      resultingMatrix[0][0], resultingMatrix[0][1], resultingMatrix[0][2],
  258.      resultingMatrix[1][0], resultingMatrix[1][1], resultingMatrix[1][2],
  259.      resultingMatrix[2][0], resultingMatrix[2][1], resultingMatrix[2][2],
  260.      resultingMatrix[3][0], resultingMatrix[3][1], resultingMatrix[3][2]);
  261.   
  262.   /* Output surface properties. Reflectance assumed == colour */
  263.   if (diffuse != 0. || specular != 0.) {
  264.     printf("    Prop prop%s%d { E{ 0.0 0.0 0.0 } p{ %g %g %g } Kd{ %g } Ks{ %g } }\n",
  265.        namePrimitive, noObject, colour.red, colour.green,
  266.        colour.blue, diffuse, specular);
  267.     colour.red = colour.green = colour.blue = 0.;
  268.     diffuse = specular = 0.;
  269.         
  270.   } else if (colour.red != 0. || colour.green != 0. || colour.blue != 0.) {
  271.     printf("    Prop prop%s%d { E{ 0.0 0.0 0.0 } p{ %g %g %g } ",
  272.         namePrimitive, noObject, colour.red, colour.green, colour.blue);
  273.     printf("Kd{ 1.0 } Ks{ 0.0 } \n");
  274.     colour.red = colour.green = colour.blue = 0.;
  275.  
  276.   } else { /* Use default properties for object == pure diffuse */
  277.     printf("    Prop prop%s%d { E{ 0.0 0.0 0.0 } ",
  278.        namePrimitive, noObject);
  279.     printf("p{ 0.0 0.0 0.0 } Kd{ 1.0 } Ks{ 0.0 } \n");
  280.   }
  281.  
  282.   /* Output meshed object patches */
  283.   OutputMeshed(namePrimitive, noObject);
  284.  
  285.   /* End delimiter */
  286.   printf("}\n");
  287.  
  288.   totalid++;
  289. }
  290.  
  291. /**********************************************************************/
  292. /* The object is a polygonal mesh */
  293. /**********************************************************************/
  294. void Surface()
  295. {
  296.   int i,j;
  297.   static int surfaceid = 0;
  298.   char *name = "mesh";
  299.   matrix tempMatrix;
  300.   
  301.   if ((SurfaceParm[0] != 1) && (SurfaceParm[1] != 1)) {
  302.     MxIdentity (primitiveMatrix);
  303.     premesh = 1;
  304.     surfaceid++;
  305.     OutputObject (name, surfaceid);
  306.   }
  307. }
  308.  
  309. /**********************************************************************/
  310. /* The object is a cone */
  311. /**********************************************************************/
  312. void Cone()
  313. {
  314.   static int coneid = 0;
  315.   char *name = "cone";
  316.   matrix tempMatrix;
  317.   
  318.   MxIdentity (primitiveMatrix);
  319.   MxScale (primitiveMatrix, 0.5, 0.5, 0.5);
  320.   primitiveMatrix[3][2] = -0.5;
  321.   coneid++;
  322.   premesh = 0;
  323.   OutputObject (name, coneid);
  324. }
  325.  
  326. /**********************************************************************/
  327. /* The object is a cube */
  328. /**********************************************************************/
  329. void Cube ()
  330. {
  331.   static int cubeid = 0;
  332.   char *name = "cube";
  333.   
  334.   MxIdentity (primitiveMatrix);
  335.   MxScale(primitiveMatrix, 0.5, 0.5, 0.5);
  336.   cubeid++;
  337.   premesh = 0;
  338.   OutputObject (name, cubeid);
  339. }
  340.  
  341. /**********************************************************************/
  342. /* The object is a cylinder */
  343. /**********************************************************************/
  344. void Cylinder()
  345. {
  346.   static int cylinderid = 0;
  347.   char *name = "cylinder";
  348.   
  349.   MxIdentity (primitiveMatrix);
  350.   MxScale(primitiveMatrix, 0.5, 0.5, 0.5);
  351.   cylinderid++;
  352.   premesh = 0;
  353.   OutputObject (name, cylinderid);
  354. }
  355.  
  356. /**********************************************************************/
  357. /* The object is a sphere */
  358. /**********************************************************************/
  359. void Sphere()
  360. {
  361.   static int sphereid = 0;
  362.   char *name = "sphere";
  363.   
  364.   MxIdentity (primitiveMatrix);
  365.   MxScale(primitiveMatrix, 0.5, 0.5, 0.5);
  366.   sphereid++;
  367.   premesh = 0;
  368.   OutputObject (name, sphereid);
  369. }
  370.  
  371. /*
  372.  * The object is a point light source (not used)
  373.  */
  374. void Light()
  375. { }
  376.  
  377. void OptikLight ()
  378. {
  379.   static int lightid = 0;
  380.   matrix resultingMatrix;
  381.   
  382.   MxIdentity (resultingMatrix);
  383.   
  384.   if (isRotateMatrix || isScaleMatrix)
  385.     {
  386.       printf ("\n /* Rotation or scale of light issued, ");
  387.       printf ("not handled. */\n\n");
  388.       isRotateMatrix = isScaleMatrix = FALSE;
  389.     }
  390.   
  391.   if (isTranslateMatrix)
  392.     {
  393.       MxMultiply (resultingMatrix, translateMatrix, resultingMatrix);
  394.       isTranslateMatrix = FALSE;
  395.     }
  396.   
  397.   if (isTransfMatrix)
  398.     {
  399.       MxMultiply (resultingMatrix, transfMatrix, resultingMatrix);
  400.       isTransfMatrix = FALSE;
  401.     }
  402.   
  403.   printf ("add light light%d point ", lightid);
  404.   
  405.   if (resultingMatrix[3][0] != 0. || resultingMatrix[3][1] != 0. ||
  406.       resultingMatrix[3][2] != 0.)
  407.     {
  408.       printf ("%g %g %g ", resultingMatrix[3][0],
  409.           resultingMatrix[3][1], resultingMatrix[3][2]);
  410.     }
  411.   else 
  412.     if (colour.red != 0. || colour.green != 0. || colour.blue != 0.)
  413.       /* default position of the light at the origin */
  414.       printf ("0 0 0 ");
  415.   
  416.   if (colour.red != 0. || colour.green != 0. || colour.blue != 0.)
  417.     {
  418.       printf ("%g %g %g ", colour.red, colour.green, colour.blue);
  419.       colour.red = colour.green = colour.blue = 0.;
  420.     }
  421.   
  422.   printf ("\n");
  423.   
  424.   if (diffuse != 0. || specular != 0.)
  425.     {
  426.       printf ("\n /* Diffusion or specularity of light issued, ");
  427.       printf ("not handled. */\n\n");
  428.       diffuse = specular = 0.;
  429.     }
  430. }
  431.  
  432. /**********************************************************************/
  433. /* Scale the object */
  434. /**********************************************************************/
  435. void Scale ()
  436. {
  437.   MxIdentity (scaleMatrix);
  438.   MxScale (scaleMatrix, VectorRead[0], VectorRead[1], VectorRead[2]);
  439.   isScaleMatrix = TRUE;
  440. }
  441.  
  442. /**********************************************************************/
  443. /* Translate the object */
  444. /**********************************************************************/
  445. void Translate ()
  446. {
  447.   MxIdentity (translateMatrix);
  448.   MxTranslate (translateMatrix, VectorRead[0], VectorRead[1],
  449.            VectorRead[2]);
  450.   isTranslateMatrix = TRUE;
  451. }
  452.  
  453. /**********************************************************************/
  454. /* Rotate the object */
  455. /**********************************************************************/
  456. void Rotate ()
  457. {
  458.   matrix tempMatrix;
  459.   
  460.   MxIdentity (rotateMatrix);
  461.   if (VectorRead[0] != 0.)
  462.     MxRotateD (rotateMatrix, VectorRead[0], 'x');
  463.   if (VectorRead[1] != 0.) {
  464.     MxIdentity (tempMatrix);
  465.     MxRotateD (tempMatrix, VectorRead[1], 'y');
  466.     MxMultiply (rotateMatrix, tempMatrix, rotateMatrix);
  467.   }
  468.   if (VectorRead[2] != 0.) {
  469.     MxIdentity (tempMatrix);
  470.     MxRotateD (tempMatrix, VectorRead[2], 'z');
  471.     MxMultiply (rotateMatrix, tempMatrix, rotateMatrix);
  472.   }
  473.   isRotateMatrix = TRUE;
  474. }
  475.  
  476. /**********************************************************************/
  477. /* Specify the emission of the surface */
  478. /**********************************************************************/
  479. void SurfColour ()
  480. {
  481.   colour.red   = VectorRead[0];
  482.   colour.green = VectorRead[1];
  483.   colour.blue  = VectorRead[2];
  484. }
  485.  
  486. /**********************************************************************/
  487. /* Specify the diffuse coefficient of the surface */
  488. /**********************************************************************/
  489. void Diffusion ()
  490. {
  491.   diffuse = value;
  492. }
  493.  
  494. /**********************************************************************/
  495. /* Specify the specular coefficient of the surface */
  496. /**********************************************************************/
  497. void Specularity ()
  498. {
  499.   specular = value;
  500. }
  501.